package com.zhangsr.zus.rpc.zus;

import com.zhangsr.zus.common.Constants;
import com.zhangsr.zus.common.URL;
import com.zhangsr.zus.remoting.api.exchange.ExchangeClient;
import com.zhangsr.zus.rpc.api.Invocation;
import com.zhangsr.zus.rpc.api.Invoker;
import com.zhangsr.zus.rpc.api.Result;
import com.zhangsr.zus.rpc.api.RpcInvocation;
import com.zhangsr.zus.rpc.api.protocol.AbstractInvoker;
import com.zhangsr.zus.rpc.api.support.RpcUtils;

import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: zhangsr
 */
public class ZusRpcInvoker<T> extends AbstractInvoker<T> {

    private final ExchangeClient[] clients;

    private final String version;

    private final ReentrantLock destroyLock = new ReentrantLock();

    private final Set<Invoker<?>> invokers;

    public ZusRpcInvoker(Class<T> serviceType, URL url, ExchangeClient[] clients, Set<Invoker<?>> invokers) {
        super(serviceType, url, new String[]{Constants.INTERFACE_KEY, Constants.GROUP_KEY, Constants.TOKEN_KEY, Constants.TIMEOUT_KEY});
        this.clients = clients;
        // get version.
        this.version = url.getParameter(Constants.VERSION_KEY, "0.0.0");
        this.invokers = invokers;
    }

    protected Result doInvoke(final Invocation invocation) throws Throwable {
        RpcInvocation inv = (RpcInvocation) invocation;
        inv.setAttachment(Constants.VERSION_KEY, version);

        int timeout = Constants.DEFAULT_TIMEOUT;

        ExchangeClient currentClient = clients[0];
        try {
            boolean isAsync = RpcUtils.isAsync(getUrl(), invocation);
            boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);
            return (Result) currentClient.request(inv, timeout).get();
        } catch (Exception e) {
            //todo
            e.printStackTrace();
        }
        //todo
        return null;
    }
}
